package com.example.websocketserver.configuration;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author liulei
 * @version 1.0
 */
@Data
@Component
@ConfigurationProperties(prefix = "ecej.iot.link.websocket")
public class WebsocketMqProxyConfig {
    /**
     * 代理服务器地址[必须开启stomp协议以及61613协议端口]
     */
    private String stompAddress;
    /**
     * 客户端连接到stomp代理服务器登录账号 默认是guest
     */
    private String systemLogin;
    /**
     * 客户端连接到stomp代理服务器登录密码 默认是guest
     */
    private String systemPasscode;
    /**
     * stomp协议数据端口
     */
    private Integer stompProxyPort;
    /**
     * 客户端连接到stomp代理服务器登录账号 默认是guest
     */
    private String clientLogin;
    /**
     * 客户端连接到stomp代理服务器登录密码 默认是guest
     */
    private String clientPasscode;
    /**
     * stomp代理mq服务器消息存放虚拟机地址
     */
    private String vHost;
    /**
     * 发送端与stomp服务器心跳设置
     */
    private Integer senderHeartbeat;
    /**
     * 接收端与stomp服务器心跳设置
     */
    private Integer receiverHeartbeat;

    private List<InetSocketAddress> addresses;
    /**
     * 中继地址供应器
     */
    private BrokerAddressSupplier brokerAddressSupplier;

    /**
     * Init.
     */
    @PostConstruct
    public void init() {
        brokerAddressSupplier = new BrokerAddressSupplier();
    }

    /**
     * 将配置的 ip:port 格式的地址列表转换为 InetSocketAddress 对象列表
     *
     * @param addresses the addresses
     */
    public void setAddresses(List<String> addresses) {
        this.addresses = addresses.stream().map(a -> {
            String[] addr = a.split(":");
            return new InetSocketAddress(addr[0], Integer.parseInt(addr[1]));
        }).collect(Collectors.toList());
        // 需要根据下标访问 addresses 因此使用ArrayList
        this.addresses = new ArrayList<>(this.addresses);
    }

    /**
     * The type BrokerAddressSupplier.
     *
     * @author xiejinhong.
     * @date 2021年06月03日 21:28:23
     */
    public class BrokerAddressSupplier implements Supplier<SocketAddress> {
        private final AtomicInteger index = new AtomicInteger();
        /**
         * 轮询中继地址
         */
        @Override
        public SocketAddress get() {
            return addresses.get(index.getAndIncrement() % addresses.size());
        }
    }
}
